<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input v-model="listQuery.a1templatetableId" size="mini" placeholder="模板表ID" style="width: 100px; " class="filter-item" @keyup.enter.native="handleFilter" />
      <select-option
        v-model="listQuery.deleteflag"
        size="mini"
        placeholder="删除标志"
        style="width: 100px; "
        class="filter-item"
        :clearable=true
        prop-name="deleteflag"
        :prop-ds-type=1
      />
      <el-select
        v-model="listQuery.ishidden"
        size="mini"
        :clearable=true
        style="width: 150px; "
        class="filter-item"
        placeholder="是否隐藏">
          <el-option
            v-for="item in optionsIshidden4query"
            :key="item.value"
            :label="item.label"
            :value="item.value"/>
      </el-select>

      <el-button :loading="queryLoading" class="filter-item" size="mini" type="primary" icon="el-icon-search" @click="handleFilter">
        查询
      </el-button>
      <el-button :loading="editAllLoading" class="filter-item" size="mini" type="primary" icon="el-icon-edit" @click="handleEditAll">
        编辑所有
      </el-button>
      <el-button :loading="saveAllLoading" class="filter-item" size="mini" type="primary" icon="el-icon-check" @click="handleSaveAll">
        保存所有
      </el-button>
      <el-button :loading="loadDbLoading" class="filter-item" style="margin-left: 0px;" size="mini" type="primary" icon="el-icon-refresh" @click="handleAutoAddColumnApi">
        自动同步数据库
      </el-button>
      <el-tag class="filter-item">提醒：1,行内单击编辑，双击保存;    2,可拖动行，改变用户最终表格列排序。</el-tag>
    </div>
    <el-table
      row-key="id"
      ref="dragTable"
      id="dragTable"
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      @sort-change="sortChange"
      :height="tableHeight"
      @row-click="handleRowClick"
      @row-dblclick="handleRowDblClick"
    >
      <el-table-column fixed="left" label="ID" prop="id" align="center" width="80">
        <template slot-scope="{row}">
          <span>{{ row.id }}</span>
        </template>
      </el-table-column>
      <el-table-column fixed="left" label="列名" width="150px" align="center">
        <template slot-scope="{row}">
          <span>{{ row.columnname }}</span>
        </template>
      </el-table-column>
      <el-table-column label="列名SQL" width="150px" align="center">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.columnnamesql" class="edit-input" size="mini" />
          <span v-else>{{ row.columnnamesql }}</span>
        </template>
      </el-table-column>
      <el-table-column label="显示名Label" width="150px" align="center">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.columnshowname" class="edit-input" size="mini" />
          <span v-else>{{ row.columnshowname }}</span>
        </template>
      </el-table-column>
      <el-table-column label="合计?" width="80px" align="center">
        <template slot-scope="{row}">
          <el-checkbox v-if="row.edit" v-model="row.needsum" size="mini" true-label="1" false-label="0"/>
          <span v-else>{{row.needsum|toBool}}</span>
        </template>
      </el-table-column>
      <el-table-column label="合计SQL" width="120px" align="center">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.columnnamesqlsum" class="edit-input" size="mini" />
          <span v-else>{{ row.columnnamesqlsum }}</span>
        </template>
      </el-table-column>
      <el-table-column label="冻结?" width="80px" align="center">
        <template slot-scope="{row}">
          <el-checkbox v-if="row.edit" v-model="row.isfrozencolumn" size="mini" true-label="1" false-label="0"/>
          <span v-else>{{row.isfrozencolumn|toBool}}</span>
        </template>
      </el-table-column>
      <el-table-column label="隐藏?" width="150" align="center">
        <template slot-scope="{row}">
          <el-select v-if="row.edit" v-model="row.ishidden" class="edit-input" size="mini" >
            <el-option
              v-for="item in optionsIshidden"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"/>
          </el-select>
          <span v-else>{{ getOptionsIshidden(row.ishidden) }}</span>
          <!--<el-select v-else v-model="row.ishidden" class="edit-input" size="mini" disabled>
            <el-option
              v-for="item in optionsIshidden"
              :key="item.value"
              :label="item.label"
              :value="item.value"/>
          </el-select>-->
        </template>
      </el-table-column>
      <el-table-column label="查询?" width="80" align="center">
        <template slot-scope="{row}">
          <el-checkbox v-if="row.edit" v-model="row.isquery" size="mini" true-label="1" false-label="0"/>
          <span v-else>{{row.isquery|toBool}}</span>
        </template>
      </el-table-column>
      <el-table-column label="编辑?" width="80" align="center">
        <template slot-scope="{row}">
          <el-checkbox v-if="row.edit" v-model="row.canadd" size="mini" true-label="1" false-label="0"/>
          <span v-else>{{row.canadd|toBool}}</span>
        </template>
      </el-table-column>

      <el-table-column label="列类型" width="120" align="center">
        <template slot-scope="{row}">
          <el-select v-if="row.edit" v-model="row.columntype" class="edit-input" size="mini" >
            <el-option
              v-for="item in optionsColumntype"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"/>
          </el-select>
          <span v-else>{{ row.columntype }}</span>
        </template>
      </el-table-column>

      <el-table-column label="多选项数据源" width="150" align="center">
        <template slot-scope="{row}">
          <el-select v-if="row.edit" v-model="row.dataresource" class="edit-input" size="mini" >
            <el-option
              v-for="item in optionsDataresource"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"/>
          </el-select>
          <span v-else>{{ getOptionsDataresource(row.dataresource) }}</span>
          <!--<el-select v-else v-model="row.dataresource" class="edit-input" size="mini" disabled>
            <el-option
              v-for="item in optionsDataresource"
              :key="item.value"
              :label="item.label"
              :value="item.value"/>
          </el-select>-->
        </template>
      </el-table-column>

      <el-table-column label="枚举类名/多选项SQL" width="250px" align="left">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.optionssql" class="edit-input" size="mini" />
          <span v-else>{{ row.optionssql }}</span>
        </template>
      </el-table-column>

      <el-table-column label="查询方式" width="120" align="center">
        <template slot-scope="{row}">
          <el-select v-if="row.edit" v-model="row.queryType" class="edit-input" size="mini" >
            <el-option
              v-for="item in optionsQueryType"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              :disabled="item.disabled"/>
          </el-select>
          <span v-else>{{ row.queryType }}</span>
        </template>
      </el-table-column>

      <el-table-column label="是否排序" width="80px" align="left">
        <template slot-scope="{row}">
          <el-checkbox v-if="row.edit" v-model="row.issortcolumn" size="mini" true-label="1" false-label="0"/>
          <span v-else>{{row.issortcolumn|toBool}}</span>
        </template>
      </el-table-column>

      <el-table-column label="表别名" width="80px" align="center">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.tablealiasname" class="edit-input" size="mini" />
          <span v-else>{{ row.tablealiasname }}</span>
        </template>
      </el-table-column>

      <el-table-column label="列宽" width="80px" align="center">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.columnwidth" class="edit-input" size="mini" />
          <span v-else>{{ row.columnwidth }}</span>
        </template>
      </el-table-column>

      <el-table-column label="sort" width="80px" align="center">
        <template slot-scope="{row}">
          <el-input v-if="row.edit" v-model="row.sort" class="edit-input" size="mini" />
          <span v-else>{{ row.sort }}</span>
        </template>
      </el-table-column>
      <el-table-column label="创建日期" width="150px" align="center">
        <template slot-scope="{row}">
          <span>{{ row.createdate | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
        </template>
      </el-table-column>

      <!--操作Button-->
      <el-table-column fixed="right" label="操作" align="center" min-width="200">
        <template slot-scope="{row,$index}">
          <el-button
            v-show="row.edit"
            type="success"
            icon="el-icon-close" title="取消"
            size="mini"
            style="margin-left: 0px;"
            @click="cancelEdit(row)"
          ></el-button>

          <el-button
            v-if="row.edit"
            type="success"
            icon="el-icon-check" title="保存"
            size="mini"
            style="margin-left: 0px;"
            @click="confirmEdit(row)"
          ></el-button>

          <el-button
            v-else
            type="primary"
            icon="el-icon-edit" title="编辑"
            size="mini"
            style="margin-left: 0px;"
            @click="row.edit=!row.edit"
          ></el-button>

          <el-button size="mini" type="danger" icon="el-icon-delete" title="删除" style="margin-left: 0px;" @click="handleDelete(row, $index)"></el-button>

        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />

  </div>
</template>

<script>
import { fetchList, updateApi, updateBatchApi, removeApi, autoAddColumnApi, editColumnSortByIds } from './tmpt-column-api'
import waves from '@/directive/waves' // waves directive
import { parseTime, deleteEmptyProperty } from '@/utils'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
// 导入多选项组件
import SelectOption from '@/components/SelectOption/SelectOption'
// drag
import Sortable from 'sortablejs'

export default {
    name: 'TmptColumnList',
    components: { Pagination, SelectOption },
    directives: { waves },
    filters: {
        statusFilter(status) {
            const statusMap = {
                published: 'success',
                draft: 'info',
                deleted: 'danger'
            }
            return statusMap[status]
        },
    },
    props: {
        a1templatetableId: Number
    },
    data() {
        return {
            tableKey: 0,
            list: [],
            total: 0,
            listLoading: false,
            queryLoading: false,
            editAllLoading: false,
            saveAllLoading: false,
            loadDbLoading: false,

            listQuery: {
                page: 1,
                limit: 200,
                sort: '+sort',
                deleteflag: 0,
                ishidden: '0',
                a1templatetableId: ''
            },
            importanceOptions: [1, 2, 3],
            sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
            statusOptions: ['published', 'draft', 'deleted'],
            showReviewer: false,
            temp: {},
            dialogFormVisible: false,
            dialogForm4CodeVisible: false,
            dialogStatus: '',
            textMap: {
              update: '编辑',
              create: '新增'
            },
            rules: {
              name: [{ required: true, message: 'name is required', trigger: 'blur' }],
              loginname: [{ required: true, message: 'loginname is required', trigger: 'blur' }]
            },
            downloadLoading: false,
            tableHeight: 100,
            // drag
            sortable: null,
            oldList: [],
            newList: [],
            // input/date/date-range/num-range/select/tree/
            optionsColumntype:[{
                value: 'input',
                label: 'input'
            }, {
                value: 'date',
                label: 'date'
            }, {
                value: 'date-range',
                label: 'date-range'
            }, {
                value: 'num-range',
                label: 'num-range'
            }, {
                value: 'select',
                label: 'select'
            }, {
                value: 'select-multi',
                label: 'select-multi'
            }, {
                value: 'tree',
                label: 'tree',
                disabled: true
            }],
            optionsQueryType:[{
                value: '',
                label: ''
            },{
                value: 'like',
                label: 'like'
            }, {
                value: 'between',
                label: 'between'
            }],
            // Options 数据源
            optionsDataresource:[{
                value: '0',
                label: '无'
            }, {
                value: '1',
                label: '枚举数据字典'
            }, {
                value: '2',
                label: 'Sql动态查询'
            }],
            //
            optionsIshidden:[{
                value: '0',
                label: '显示'
            }, {
                value: '1',
                label: '彻底隐藏'
            }, {
                value: '2',
                label: '隐藏表头，行展开中显示'
            }],
            optionsIshidden4query:[{
                value: '0',
                label: '可显示'
            }, {
                value: '1',
                label: '彻底隐藏'
            }],


        }
    },
    computed: {
        getOptionsDataresource() {
            return function(val) {
                if (val===null || val===undefined) {
                    val = '0';
                }
                return this.optionsDataresource.filter(item=> ''+item.value===val)[0].label
            }
        },
        getOptionsIshidden() {
            return function(val) {
                if (val===null || val===undefined) {
                    val = '0';
                }
                return this.optionsIshidden.filter(item=> ''+item.value===val)[0].label
            }
        }
    },
    watch: {
        'a1templatetableId': {
            immediate: true, // vue首次赋值不触发watch的解决方法
            handler: function(nval){
                this.listQuery.a1templatetableId = nval
                this.getList()
            }
        }
    },
    created() {
        const clientHeight = `${document.documentElement.clientHeight}`;//获取浏览器可视区域高度
        this.tableHeight = clientHeight - 350
    },
    methods: {
        getList() {
          this.queryLoading = true
          this.listLoading = true
          deleteEmptyProperty(this.listQuery)
          fetchList(this.listQuery).then(result => {
            const items = result.map.rows
            this.total = result.map.total

            // 备份数据，编辑还原用
            this.list = items.map(v => {
              this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
              v.original = Object.assign({}, v)
              return v
            })
            this.listLoading = false
            this.queryLoading = false

            this.oldList = this.list.map(v => v.id)
            this.newList = this.oldList.slice()
            // drag
            this.$nextTick(() => {
              this.rowDrag()
            })
          })
        },
        // drag
        rowDrag() {
          //const el = this.$refs.dragTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
          const tbody = document.getElementById("dragTable").querySelector('.el-table__body-wrapper tbody')
          const _this = this
          this.sortable = Sortable.create(tbody, {
            ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
            setData: function(dataTransfer) {
              // to avoid Firefox bug
              // Detail see : https://github.com/RubaXa/Sortable/issues/1012
              dataTransfer.setData('Text', '')
            },
            onEnd: evt => {
              const targetRow = _this.list.splice(evt.oldIndex, 1)[0]
                _this.list.splice(evt.newIndex, 0, targetRow)

              // for show the changes, you can delete in you code
              const tempIndex = _this.newList.splice(evt.oldIndex, 1)[0]
                _this.newList.splice(evt.newIndex, 0, tempIndex)

              // update remotely
              if (_this.a1templatetableId !== undefined) {
                editColumnSortByIds(this.newList).then(r => {
                  console.log(JSON.stringify(r))
                })
              }
            }
          })
        },
        handleFilter() {
          this.listQuery.page = 1
          this.getList()
        },
        sortChange(data) {
          const { prop, order } = data
          if (prop === 'sort') {
            this.sortByID(order)
          }
        },
        sortByID(order) {
          if (order === 'ascending') {
            this.listQuery.sort = '+sort'
          } else {
            this.listQuery.sort = '-sort'
          }
          this.handleFilter()
        },

        // 同步数据库
        handleAutoAddColumnApi() {
            this.loadDbLoading = true
            autoAddColumnApi({ _id: this.listQuery.a1templatetableId }).then(result => {
                this.loadDbLoading = false
                this.notify(result)
                if (result.success) {
                    this.getList()
                }
            })
        },

        cancelEdit(row) {
            // 还原原始值
            Object.keys(row).forEach(key => {
                if (key !== 'original' && key !== 'edit') {
                    row[key] = row.original[key]
                }
            })
            row.edit = false
            // row.original.edit = false
            this.$message({
                message: '数据恢复到原始值',
                type: 'warning'
            })
        },

        confirmEdit(row) {
            const param = Object.assign({}, row)
            param.original = {}
            updateApi(param).then((result) => {
                this.notify(result)
                if (result.success) {
                    row.edit = false
                    // 原始值：更新生成最新输入值
                    Object.keys(row).forEach(key => {
                        if (key !== 'original' && key !== 'edit') {
                            row.original[key] = row[key]
                        }
                    })
                }
            })
        },
        // handleEditAll
        handleEditAll: function () {
            const _this = this
            this.editAllLoading = true
            this.listLoading = true
            setTimeout(function () {
                _this.list.forEach(row => {
                    row.edit = true
                })
            }, 500)
            setTimeout(function () {
                _this.listLoading = false
                _this.editAllLoading = false
            }, 2000)
        },
        // handleSaveAll
        handleSaveAll: function () {
            this.saveAllLoading = true
            this.listLoading = true
            const paramList = []
            this.list.forEach( row=> {
                if (row.edit) {
                    const param = Object.assign({}, row)
                    param.original = {}
                    paramList.push(param)
                }
            })
            updateBatchApi(paramList).then((result) => {
                this.notify(result)
                this.saveAllLoading = false
                this.listLoading = false
                if (result.success) {
                    this.list.forEach(row => {
                        row.edit = false
                        // 原始值：更新生成最新输入值
                        Object.keys(row).forEach(key => {
                            if (key !== 'original' && key !== 'edit') {
                                row.original[key] = row[key]
                            }
                        })
                    })
                }
            })

        },
        // delete
        handleDelete(row) {
            this.$confirm('确认删除吗？')
                .then(_ => {
                    // delete api
                    removeApi({ id: '' + row.id }).then((result) => {
                        this.notify(result)
                        if (result.success) {
                            this.getList()
                        }
                    })
                    // end
                })
                .catch(_ => {})
        },
        //
        formatJson(filterVal) {
            return this.list.map(v => filterVal.map(j => {
                if (j === 'timestamp') {
                    return parseTime(v[j])
                } else {
                    return v[j]
                }
            }))
        },
        getSortClass: function(key) {
            const sort = this.listQuery.sort
            return sort === `+${key}` ? 'ascending' : 'descending'
        },
        handleRowClick: function (row, column, event) {
            row.edit=true
        },
        handleRowDblClick: function (row, column, event) {
            row.edit=false
            this.confirmEdit(row)
        }
    }
}
</script>

<style>
  .sortable-ghost{
    opacity: .8;
    color: darkgreen!important;
    background: #42b983!important;
  }
</style>

<style scoped>
  .icon-star{
    margin-right:2px;
  }
  .drag-handler{
    width: 20px;
    height: 20px;
    cursor: pointer;
  }
  .show-d{
    margin-top: 15px;
  }


</style>
